# -*- coding: utf-8 -*-
"""
定时任务业务逻辑层

负责定时任务的业务逻辑处理，包括任务调度、执行监控、错误处理等
"""
import asyncio
import time
from typing import Dict, Any, Optional, List, Callable
from datetime import datetime, timedelta
from app.repositories.task_repository import TaskRepository, ExternalApiRepository, TaskConfigRepository

# 导入原有的任务函数
from task.goods import task_save_good
from task.goods_brand import task_save_good_brand
from task.stock_info import task_save_stock_change
from task.refund_info import task_save_refund, task_save_refund_logistics
from task.base_info import (
    task_save_shop, task_save_logistics, task_save_warehouse, task_save_provider,
    query_stockout_orders, query_logistics_sync, query_sales_trade, query_sales_api_trade
)


class TaskExecutionService:
    """任务执行服务基类"""
    
    def __init__(self):
        self.task_repo = TaskRepository()
        self.api_repo = ExternalApiRepository()
        self.config_repo = TaskConfigRepository()
    
    async def execute_task_with_logging(self, task_name: str, task_type: str, 
                                       task_func: Callable, *args, **kwargs) -> Dict[str, Any]:
        """执行任务并记录日志"""
        start_time = datetime.now()
        log_id = None
        
        try:
            # 检查任务是否启用
            if not self.config_repo.is_task_enabled(task_name):
                return {
                    "success": False,
                    "message": f"任务 {task_name} 已禁用",
                    "task_name": task_name
                }
            
            # 记录任务开始
            log_id = self.task_repo.log_task_execution(
                task_name=task_name,
                task_type=task_type,
                status="running",
                start_time=start_time
            )
            
            # 执行任务
            if asyncio.iscoroutinefunction(task_func):
                result = await task_func(*args, **kwargs)
            else:
                result = task_func(*args, **kwargs)
            
            end_time = datetime.now()
            duration = (end_time - start_time).total_seconds()
            
            # 更新任务状态为成功
            if log_id:
                self.task_repo.update_task_status(
                    log_id=log_id,
                    status="success",
                    end_time=end_time,
                    result_message=f"任务执行成功，耗时 {duration:.2f} 秒"
                )
            
            return {
                "success": True,
                "message": f"任务 {task_name} 执行成功",
                "task_name": task_name,
                "duration": duration,
                "result": result
            }
            
        except Exception as e:
            end_time = datetime.now()
            duration = (end_time - start_time).total_seconds()
            error_message = f"任务执行失败: {str(e)}"
            
            # 更新任务状态为失败
            if log_id:
                self.task_repo.update_task_status(
                    log_id=log_id,
                    status="failed",
                    end_time=end_time,
                    error_message=error_message
                )
            
            print(f"任务 {task_name} 执行失败: {str(e)}")
            
            return {
                "success": False,
                "message": error_message,
                "task_name": task_name,
                "duration": duration
            }


class GoodsTaskService(TaskExecutionService):
    """商品相关任务服务"""
    
    def __init__(self):
        super().__init__()
    
    def get_date_range(self, start_date: Optional[datetime] = None) -> List[Dict[str, str]]:
        """获取日期范围"""
        try:
            # 设置起始日期
            if not start_date:
                start_date = datetime(2024, 1, 1)
            
            # 获取当前日期
            end_date = datetime.now()
            
            # 存储日期的列表
            date_list = []
            current_date = start_date
            
            # 循环直到当前日期
            while current_date <= end_date:
                date_str = current_date.strftime('%Y-%m-%d %H:%M:%S')
                next_date = current_date + timedelta(days=1)
                date_list.append({
                    "day1": date_str,
                    "day2": next_date.strftime('%Y-%m-%d %H:%M:%S')
                })
                current_date = next_date
                
            return date_list
            
        except Exception as e:
            print(f"生成日期列表失败: {str(e)}")
            return []
    
    async def sync_goods_data(self, enable_batch: bool = False) -> Dict[str, Any]:
        """同步商品数据"""
        if enable_batch:
            # 批量同步历史数据
            date_ranges = self.get_date_range()
            total_processed = 0
            
            for date_range in date_ranges:
                time.sleep(1)  # 避免API频率限制
                print(f"同步商品数据: {date_range['day1']} 到 {date_range['day2']}")
                
                result = await self.execute_task_with_logging(
                    task_name="goods_sync_batch",
                    task_type="goods",
                    task_func=task_save_good,
                    start_time=date_range["day1"],
                    end_time=date_range["day2"]
                )
                
                if result["success"] and result.get("result"):
                    total_processed += result["result"].get("processed_count", 0)
            
            return {
                "success": True,
                "message": f"批量同步完成，共处理 {total_processed} 个商品",
                "total_processed": total_processed
            }
        else:
            # 增量同步
            yesterday = datetime.now() - timedelta(days=1)
            today = datetime.now()
            
            return await self.execute_task_with_logging(
                task_name="goods_sync",
                task_type="goods",
                task_func=task_save_good,
                start_time=yesterday.strftime('%Y-%m-%d %H:%M:%S'),
                end_time=today.strftime('%Y-%m-%d %H:%M:%S')
            )
    
    async def sync_goods_brand(self) -> Dict[str, Any]:
        """同步商品品牌"""
        return await self.execute_task_with_logging(
            task_name="goods_brand_sync",
            task_type="goods",
            task_func=task_save_good_brand
        )


class StockTaskService(TaskExecutionService):
    """库存相关任务服务"""
    
    def __init__(self):
        super().__init__()
    
    async def sync_stock_changes(self) -> Dict[str, Any]:
        """同步库存变更"""
        return await self.execute_task_with_logging(
            task_name="stock_sync",
            task_type="stock",
            task_func=task_save_stock_change
        )


class RefundTaskService(TaskExecutionService):
    """退款相关任务服务"""
    
    def __init__(self):
        super().__init__()
    
    async def sync_refund_data(self) -> Dict[str, Any]:
        """同步退款数据"""
        # 同步退款信息
        refund_result = await self.execute_task_with_logging(
            task_name="refund_sync",
            task_type="refund",
            task_func=task_save_refund
        )
        
        # 同步退款物流
        logistics_result = await self.execute_task_with_logging(
            task_name="refund_logistics_sync",
            task_type="refund",
            task_func=task_save_refund_logistics
        )
        
        return {
            "success": refund_result["success"] and logistics_result["success"],
            "refund_result": refund_result,
            "logistics_result": logistics_result
        }


class OrderTaskService(TaskExecutionService):
    """订单相关任务服务"""
    
    def __init__(self):
        super().__init__()
    
    async def sync_order_data(self) -> Dict[str, Any]:
        """同步订单数据"""
        # 同步出库单
        stockout_result = await self.execute_task_with_logging(
            task_name="stockout_sync",
            task_type="order",
            task_func=query_stockout_orders
        )
        
        # 同步销售订单
        sales_result = await self.execute_task_with_logging(
            task_name="sales_sync",
            task_type="order",
            task_func=query_sales_api_trade
        )
        
        return {
            "success": stockout_result["success"] and sales_result["success"],
            "stockout_result": stockout_result,
            "sales_result": sales_result
        }


class LogisticsTaskService(TaskExecutionService):
    """物流相关任务服务"""
    
    def __init__(self):
        super().__init__()
    
    async def sync_logistics_data(self) -> Dict[str, Any]:
        """同步物流数据"""
        return await self.execute_task_with_logging(
            task_name="logistics_sync",
            task_type="logistics",
            task_func=query_logistics_sync
        )


class BaseInfoTaskService(TaskExecutionService):
    """基础信息任务服务"""
    
    def __init__(self):
        super().__init__()
    
    async def sync_base_info(self) -> Dict[str, Any]:
        """同步基础信息"""
        results = {}
        
        # 同步店铺信息
        results["shop"] = await self.execute_task_with_logging(
            task_name="shop_sync",
            task_type="base_info",
            task_func=task_save_shop
        )
        
        # 同步物流信息
        results["logistics"] = await self.execute_task_with_logging(
            task_name="logistics_info_sync",
            task_type="base_info",
            task_func=task_save_logistics
        )
        
        # 同步仓库信息
        results["warehouse"] = await self.execute_task_with_logging(
            task_name="warehouse_sync",
            task_type="base_info",
            task_func=task_save_warehouse
        )
        
        # 同步供应商信息
        results["provider"] = await self.execute_task_with_logging(
            task_name="provider_sync",
            task_type="base_info",
            task_func=task_save_provider
        )
        
        success_count = sum(1 for r in results.values() if r["success"])
        total_count = len(results)
        
        return {
            "success": success_count == total_count,
            "message": f"基础信息同步完成 ({success_count}/{total_count})",
            "results": results
        }


class MaintenanceTaskService(TaskExecutionService):
    """维护任务服务"""
    
    def __init__(self):
        super().__init__()
    
    async def backup_database(self) -> Dict[str, Any]:
        """数据库备份"""
        def backup_func():
            print(f"开始数据库备份: {datetime.now()}")
            # TODO: 实现实际的备份逻辑
            print(f"数据库备份完成: {datetime.now()}")
            return {"backup_file": f"backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.sql"}
        
        return await self.execute_task_with_logging(
            task_name="database_backup",
            task_type="maintenance",
            task_func=backup_func
        )


class TaskManagementService:
    """任务管理服务"""
    
    def __init__(self):
        self.task_repo = TaskRepository()
        self.config_repo = TaskConfigRepository()
        
        # 初始化各个任务服务
        self.goods_service = GoodsTaskService()
        self.stock_service = StockTaskService()
        self.refund_service = RefundTaskService()
        self.order_service = OrderTaskService()
        self.logistics_service = LogisticsTaskService()
        self.base_info_service = BaseInfoTaskService()
        self.maintenance_service = MaintenanceTaskService()
    
    def get_task_execution_history(self, task_name: Optional[str] = None,
                                  task_type: Optional[str] = None,
                                  page: int = 1, page_size: int = 20) -> Dict[str, Any]:
        """获取任务执行历史"""
        try:
            limit = page_size
            history = self.task_repo.get_task_execution_history(
                task_name=task_name,
                task_type=task_type,
                limit=limit
            )
            
            return {
                "success": True,
                "data": {
                    "history": history,
                    "page": page,
                    "page_size": page_size,
                    "total": len(history)
                }
            }
        except Exception as e:
            return {
                "success": False,
                "message": f"获取任务历史失败: {str(e)}"
            }
    
    def get_task_statistics(self, task_type: Optional[str] = None,
                           days: int = 7) -> Dict[str, Any]:
        """获取任务统计"""
        try:
            stats = self.task_repo.get_task_statistics(task_type=task_type, days=days)
            return {
                "success": True,
                "data": stats
            }
        except Exception as e:
            return {
                "success": False,
                "message": f"获取任务统计失败: {str(e)}"
            }
    
    def update_task_config(self, task_name: str, config: Dict[str, Any]) -> Dict[str, Any]:
        """更新任务配置"""
        try:
            success = self.config_repo.update_task_config(task_name, config)
            if success:
                return {
                    "success": True,
                    "message": "任务配置更新成功"
                }
            else:
                return {
                    "success": False,
                    "message": "任务配置更新失败"
                }
        except Exception as e:
            return {
                "success": False,
                "message": f"更新任务配置失败: {str(e)}"
            }
    
    async def execute_manual_task(self, task_name: str, task_params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """手动执行任务"""
        try:
            task_params = task_params or {}
            
            # 根据任务名称调用对应的服务
            if task_name == "goods_sync":
                return await self.goods_service.sync_goods_data(
                    enable_batch=task_params.get("enable_batch", False)
                )
            elif task_name == "goods_brand_sync":
                return await self.goods_service.sync_goods_brand()
            elif task_name == "stock_sync":
                return await self.stock_service.sync_stock_changes()
            elif task_name == "refund_sync":
                return await self.refund_service.sync_refund_data()
            elif task_name == "order_sync":
                return await self.order_service.sync_order_data()
            elif task_name == "logistics_sync":
                return await self.logistics_service.sync_logistics_data()
            elif task_name == "base_info_sync":
                return await self.base_info_service.sync_base_info()
            elif task_name == "database_backup":
                return await self.maintenance_service.backup_database()
            else:
                return {
                    "success": False,
                    "message": f"未知的任务名称: {task_name}"
                }
                
        except Exception as e:
            return {
                "success": False,
                "message": f"手动执行任务失败: {str(e)}"
            } 